<?php
// +----------------------------------------------------------------------
// | ThinkBLOG (Build on ThinkPHP)
// +----------------------------------------------------------------------
// | @link ( http://www.yurnero.net )
// +----------------------------------------------------------------------
// | @licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | @author nicholas <nicholasinlove@126.com>
// +----------------------------------------------------------------------
// | $Id: Rbac.class.php 136 2012-04-19 06:56:51Z nicholasinlove1986@gmail.com $
// +----------------------------------------------------------------------


class Rbac {
	
	public static $_actionList = array ();
	
	/**
	 * 用户登录认证方法
	 *
	 * @access public
	 * @param string $map
	 * @param string $model 模型
	 * 
	 * @return void
	 */
	static public function authenticate($map, $model = '') {
		if (empty ( $model ))
			$model = C ( 'USER_AUTH_MODEL' );
		
		//使用给定的Map进行认证
		return M ( $model )->where ( $map )->find ();
	}
	
	/**
	 * 取得当前认证号的所有权限列表
	 *
	 * @access public
	 * @param string $authId 用户id
	 * @param string $model 模型
	 * 
	 * @return array
	 */
	static public function getAccessList($authId, $model = '') {
		if (isset ( self::$_actionList [$authId] ))
			return self::$_actionList [$authId];
		if (empty ( $model ))
			$model = C ( 'USER_AUTH_MODEL' );
		$roleid = M ( $model )->where ( "userid=$authId" )->getField ( 'roleid' );
		$list = M ( C ( 'USER_ROLE_MODEL' ) )->where ( "roleid=$roleid" )->find ();
		$action_list = explode ( ',', strtolower ( $list ['roleaction'] ) . ',index_index' );
		foreach ( $action_list as $k => $v ) {
			unset ( $action_list [$k] );
			$action_list [$v] = $v;
		}
		self::$_actionList [$authId] = $action_list;
		return self::$_actionList [$authId];
	}
	
	/**
	 * 检查当前操作是否需要认证
	 *
	 * @access public
	 * @return boolean
	 */
	static public function checkAccess() {
		//如果项目要求认证，并且当前模块需要认证，则进行权限认证
		if (C ( 'USER_AUTH_ON' )) {
			$_module = array ();
			$_action = array ();
			if ("" != C ( 'REQUIRE_AUTH_MODULE' )) {
				//需要认证的模块
				$_module ['yes'] = explode ( ',', strtoupper ( C ( 'REQUIRE_AUTH_MODULE' ) ) );
			} else {
				//无需认证的模块
				$_module ['no'] = explode ( ',', strtoupper ( C ( 'NOT_AUTH_MODULE' ) ) );
			}
			//检查当前模块是否需要认证
			if ((! empty ( $_module ['no'] ) && ! in_array ( strtoupper ( MODULE_NAME ), $_module ['no'] )) || (! empty ( $_module ['yes'] ) && in_array ( strtoupper ( MODULE_NAME ), $_module ['yes'] ))) {
				if ("" != C ( 'REQUIRE_AUTH_ACTION' )) {
					//需要认证的操作
					$_action ['yes'] = explode ( ',', strtoupper ( C ( 'REQUIRE_AUTH_ACTION' ) ) );
				} else {
					//无需认证的操作
					$_action ['no'] = explode ( ',', strtoupper ( C ( 'NOT_AUTH_ACTION' ) ) );
				}
				//检查当前操作是否需要认证
				if ((! empty ( $_action ['no'] ) && ! in_array ( strtoupper ( ACTION_NAME ), $_action ['no'] )) || (! empty ( $_action ['yes'] ) && in_array ( strtoupper ( ACTION_NAME ), $_action ['yes'] ))) {
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		}
		return false;
	}
	
	/**
	 * 权限认证的过滤器方法
	 *
	 * @access public
	 * @param string $appName
	 * @return boolean
	 */
	static public function AccessDecision($appName = APP_NAME) {
		if (self::checkAccess ()) {
			global $_T;
			if ($_T ['userid'] < 1) {
				return false;
			}
			if ($_T ['roleid'] == 1) {
				
				return true;
			} else {
				$accessList = self::getAccessList ( $_T ['userid'] );
				$format = strtolower ( MODULE_NAME . '_' . ACTION_NAME );
				if (! isset ( $accessList [$format] )) {
					return false;
				}
			}
		}
		return true;
	}
	
	/**
	 * 判断管理员对某一个操作是否有权限
	 *
	 * @access public
	 * @param string $priv_str 操作标识
	 * @return boolean
	 */
	static public function checkPriv($priv_str) {
		global $_T;
		if ($_T ['roleid'] == 1) {
			return true;
		} else {
			$accessList = self::getAccessList ( $_T ['userid'] );
			if (! isset ( $accessList [strtolower ( $priv_str )] )) {
				return false;
			} else {
				return true;
			}
		}
	}

}